package com.glink.manage.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.glink.common.contants.BaseCodeConstants;
import com.glink.common.contants.BaseConstants;
import com.glink.common.exception.GeneralSimpleException;
import com.glink.common.util.BaseCommonUtils;
import com.glink.manage.common.BeanKit;
import com.glink.manage.common.CheckDataUtil;
import com.glink.manage.common.Constants;
import com.glink.manage.domain.UserBean;
import com.glink.manage.domain.UserRoleRelaBean;
import com.glink.manage.domain.UserThirdPartyBean;
import com.glink.manage.dto.user.*;
import com.glink.manage.mapper.UserMapper;
import com.glink.manage.service.*;
import com.glink.manage.vo.role.RoleBaseVO;
import com.glink.manage.vo.user.*;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static java.util.Objects.nonNull;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : qiushaoshan
 * @create 2024/6/18 10:27
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, UserBean> implements UserService {


    /**
     * 参建单位角色
     */
    @Value("${user.default_role.participating_unit:CJDW}")
    private String roleParticipatingUnit;

    /**
     * 系统管理员角色
     */
    @Value("${user.default_role.system_admin:ADMIN}")
    private String roleSystemAdmin;

    /**
     * 总部管理员角色
     */
    @Value("${user.default_role.head_office:ZB}")
    private String roleHeadOffice;

    /**
     * 项目部角色
     */
    @Value("${user.default_role.project_department:XMB}")
    private String roleProjectDepartment;

    /**
     * 总包单位管理员角色
     */
    @Value("${user.default_role.general_contracting:ZBDW}")
    private String roleGeneralContracting;
    
    @Autowired
    private PasswordService passwordService;
    
    @Autowired
    private UserRoleRelaService userRoleRelaService;
    
    @Autowired
    private OrgService orgService;
    
    @Autowired
    private RoleService roleService;
    
    @Autowired
    private UserThirdPartyService userThirdPartyService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    @Lazy
    private PersonManageService personManageService;
    
    /**
     * 默认24小时
     */
    @Value("${redis.user.second.expiration:86400}")
    private Long userKeyExpiration;
    
    /**
     * 新增用户
     *
     * @param userSaveDTO 保存入参
     * @return 返回状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean insertUser(UserSaveDTO userSaveDTO) throws GeneralSimpleException {
        return insertUser(userSaveDTO, BaseCommonUtils.generateUUID());
    }

    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean insertUser(UserSaveDTO userSaveDTO, String userId) throws GeneralSimpleException {
        //校验用户角色，参建单位不能和其它管理员并存
        checkUserRole(userSaveDTO.getRoleIdList());
        
        // 校验手机号
        throwIfMobileNotRule(userSaveDTO.getPhone());
        // 校验邮箱
        throwIfEmailNotRule(userSaveDTO.getEmail());

        // 校验用户编号
        checkUserNumber(null, userSaveDTO.getUserNumber());

        // insert
        String name = userSaveDTO.getUserName();
        final String _Id = userId;
        final UserBean other = findTop(x -> x.eq(UserBean::getUserName, name).ne(UserBean::getId, _Id));
        if (nonNull(other)) {
            throw new GeneralSimpleException("400008", "用户重复(姓名: " + name + "),不能新增");
        }
        UserBean user = BeanKit.copyProperties(userSaveDTO, UserBean::new);
        user.setId(_Id);

        // 默认密码
        // 加密明文密码
        String password = encryptPassword(user.getId());
        user.setPwd(password);
        boolean status = this.save(user);
        if(status){
            status = saveRoleInfo(user.getId(), userSaveDTO.getRoleIdList());
            return status;
        }
        return false;
    }

    /**
     * 校验角色信息，参建单位角色不能和其它管理员共存
     * @param roleIdList
     */
    private void checkUserRole(List<String> roleIdList) throws GeneralSimpleException {
        if(CollectionUtils.isEmpty(roleIdList)){
            return;
        }
        if(roleIdList.contains(roleParticipatingUnit)){
            if(roleIdList.contains(roleSystemAdmin) || roleIdList.contains(roleProjectDepartment) || roleIdList.contains(roleHeadOffice)){
                String orgName = orgService.findOrgNameByOrgId(roleParticipatingUnit);

                throw new GeneralSimpleException("400049", orgName);    
            }
        }
    }

    /**
     * 检查手机号是否符合要求
     * @param mobile 手机号
     * @throws GeneralSimpleException 异常信息
     */
    private void throwIfMobileNotRule(String mobile) throws GeneralSimpleException {
        if(StringUtils.isNotBlank(mobile)){
            String pat = "^1[3-9]\\d{9}$";
            Pattern pattern = Pattern.compile(pat);
            Matcher matcher = pattern.matcher(mobile);
            if (!matcher.find()) {
                log.info("mobile-{} 不符合要求-11位数字", mobile);
                throw new GeneralSimpleException("400018");
            }
        }
    }

    /**
     * 检查手机号是否符合要求
     * @param email 邮箱
     * @throws GeneralSimpleException 异常信息
     */
    private void throwIfEmailNotRule(String email) throws GeneralSimpleException {
        if(StringUtils.isNotBlank(email)){
            String pat = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
            Pattern pattern = Pattern.compile(pat);
            Matcher matcher = pattern.matcher(email);
            if (!matcher.find()) {
                log.info("email-{} 不符合要求", email);
                throw new GeneralSimpleException("400019");
            }
        }
    }

    /**
     * 校验用户编号
     * @param userId 用户ID
     * @param userNumber 用户编号
     * @throws GeneralSimpleException 异常信息
     */
    private void checkUserNumber(String userId, String userNumber) throws GeneralSimpleException {
        if(StringUtils.isNotBlank(userNumber)){
            UserBean userBean = this.lambdaQuery()
                    .ne(StringUtils.isNotEmpty(userId), UserBean::getId, userId)
                    .eq(UserBean::getUserNumber, userNumber)
                    .one();
            if (Objects.nonNull(userBean)) {
                throw new GeneralSimpleException("400015", userNumber);
            }
            
            if(!CheckDataUtil.userNumber(userNumber)){
                log.error("用户编号不可输入中文和特殊字符,{}", userNumber);
                throw new GeneralSimpleException("400033", userNumber);
            }
        }
    }
    
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean updateUser(UserUpdateDTO userUpdateDTO) throws GeneralSimpleException {
        
        String userId = userUpdateDTO.getUserId();
        // update
        if (StringUtils.isNotBlank(userId)) {
            
            try {
                redisTemplate.delete(BaseConstants.REDIS_USER_PREFIX + userId);
            } catch (Exception e) {
                log.error("更新用户{}，redis更新失败", userId);
            }

            //校验用户角色，参建单位不能和其它管理员并存
            checkUserRole(userUpdateDTO.getRoleIdList());
            
            // 校验手机号
            throwIfMobileNotRule(userUpdateDTO.getPhone());
            // 校验邮箱
            throwIfEmailNotRule(userUpdateDTO.getEmail());
            // 校验用户编号
            checkUserNumber(userId, userUpdateDTO.getUserNumber());
            
            UserBean one = findTop(x -> x.eq(UserBean::getId, userId));
            if (nonNull(one)) {
                BeanKit.copyPropertiesIgnoreNull(userUpdateDTO, one);
                boolean status = update(one, Wrappers.lambdaQuery(UserBean.class)
                        .eq(UserBean::getId, userId));
                if(status){
                    status = saveRoleInfo(one.getId(), userUpdateDTO.getRoleIdList());
                    if(status){
                        if(StringUtils.equals(one.getStatus(), BaseCodeConstants.CodeType_UserStatus.KEY_UserStatus02)){
                            // 账号禁用，token过期
                            String key = BaseConstants.REDIS_USER_TOKEN_PREFIX + one.getUserName() + "_*";
                            Set<String> keys = redisTemplate.keys(key);
                            if(org.apache.commons.collections.CollectionUtils.isNotEmpty(keys)){
                                for (String keyStr : keys) {
                                    redisTemplate.delete(keyStr);
                                }
                            }
                        }
                    }
                    return status;
                }
                return false;
            }
        }
       
        return false;
    }

    /**
     * 保存角色信息
     *
     * @param userId 用户ID
     * @param roleIdList 角色Id
     * @return 保存状态
     */
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean saveRoleInfo(String userId, List<String> roleIdList) throws GeneralSimpleException {
        if(CollectionUtils.isNotEmpty(roleIdList)){
            List<UserRoleRelaBean> roleRelaBeanList = Lists.newArrayList();
            for (int i = 0; i < roleIdList.size(); i++) {
                String roleId = roleIdList.get(i);
                RoleBaseVO roleBaseVO = roleService.findByRoleId(roleId);
                if(Objects.isNull(roleBaseVO)){
                    throw new GeneralSimpleException("401001", roleId);
                }

                // 给用户新增角色信息
                UserRoleRelaBean userRoleRelaBean = new UserRoleRelaBean();
                userRoleRelaBean.setId(BaseCommonUtils.generateUUID());
                userRoleRelaBean.setUserId(userId);
                userRoleRelaBean.setRoleId(roleId);
                roleRelaBeanList.add(userRoleRelaBean);
            }
            Integer count = userRoleRelaService.lambdaQuery().eq(UserRoleRelaBean::getUserId, userId).count();
            if(Objects.nonNull(count) && count > 0){
                boolean status = userRoleRelaService.lambdaUpdate().eq(UserRoleRelaBean::getUserId, userId)
                        .remove();
                if(!status){
                    return false;
                }
            }
           
            return userRoleRelaService.saveBatch(roleRelaBeanList);
        }
        return false;
    }
    
    /**
     * 根据用户账号获取用户信息
     *
     * @param userName 用户账号
     * @return 用户信息
     */
    @Override
    public UserVO findByUserName(String userName) {
        
        if(StringUtils.isNotBlank(userName)){
            UserBean userBean = this.lambdaQuery().eq(UserBean::getUserName, userName).one();
            return entityToVO(userBean);
        }
        
        return null;
    }

    /**
     * 变更用户状态
     *
     * @param statusDTO 用户信息
     * @return 更新状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean updateStatus(UserStatusDTO statusDTO) throws GeneralSimpleException {
        
        UserBean userBean = findTop(x -> x.eq(UserBean::getId, statusDTO.getUserId()));
        if(Objects.nonNull(userBean)){
            boolean status = this.lambdaUpdate().set(StringUtils.isNotEmpty(statusDTO.getStatus()), UserBean::getStatus, statusDTO.getStatus())
                    .eq(UserBean::getId, statusDTO.getUserId()).update();
            if(status){
                // 账号禁用，token过期
                String key = BaseConstants.REDIS_USER_TOKEN_PREFIX + userBean.getUserName() + "_*";
                Set<String> keys = redisTemplate.keys(key);
                if(org.apache.commons.collections.CollectionUtils.isNotEmpty(keys)){
                    for (String keyStr : keys) {
                        redisTemplate.delete(keyStr);
                    }
                }
            }
        }else{
            throw new GeneralSimpleException("400020", statusDTO.getUserId());
        }
        
        return false;
    }

    /**
     * 分页查询用户信息
     *
     * @param pageDTO 查询条件
     * @return 用户信息
     */
    @Override
    public IPage<UserPageVO> findUserPage(UserPageDTO pageDTO) throws GeneralSimpleException {

        List<String> userIdList = null;
        if(StringUtils.isNotBlank(pageDTO.getRoleId())){
            userIdList = userRoleRelaService.findUserIdByRoleId(pageDTO.getRoleId());
        }
        
        IPage<UserBean> userBeanIPage = new Page<>(pageDTO.getPage(), pageDTO.getSize());
        // 获取组织ID
        List<String> orgIdList = Lists.newArrayList();
        boolean headOffice = checkHeadOffice();
        boolean adminByUser = checkAdminByUser();
        
        if(StringUtils.isNotBlank(pageDTO.getOrgId())){
            if(headOffice || adminByUser){
                // 系统管理员或者总部管理员查看全部人员
                if(StringUtils.equals(pageDTO.getOrgId(), Constants.PARTICIPATION_UNIT_ORG_ID)){
                    orgIdList = orgService.findAllParticipatingUnitId();
                }else{
                    orgIdList = orgService.findOrgTreeIdByOrgId(pageDTO.getOrgId());
                }
            }else{
                orgIdList = orgService.findOrgTreeIdByOrgId(pageDTO.getOrgId());
            }
            if(CollectionUtils.isEmpty(orgIdList)){
                return new Page<>(pageDTO.getPage(), pageDTO.getSize());
            }
        }


        List<String> dataPermissionOrgIdList = null;
        if(!headOffice && !adminByUser){
            dataPermissionOrgIdList = orgService.getDataPermissionOrgId();
        }

        IPage<UserBean> page = this.lambdaQuery()
                .and(StringUtils.isNotEmpty(pageDTO.getSearchStr()), 
                        tempWrapper -> tempWrapper.like(UserBean::getFullName, pageDTO.getSearchStr())
                                .or()
                                .like(UserBean::getUserName, pageDTO.getSearchStr()))
                .in((!headOffice && !adminByUser) && CollectionUtils.isNotEmpty(dataPermissionOrgIdList), UserBean::getOrgId, dataPermissionOrgIdList)
                .eq(StringUtils.isNotEmpty(pageDTO.getStatus()), UserBean::getStatus, pageDTO.getStatus())
                .in(CollectionUtils.isNotEmpty(userIdList), UserBean::getId, userIdList)
                .in(CollectionUtils.isNotEmpty(orgIdList), UserBean::getOrgId, orgIdList)
                .orderByDesc(UserBean::getCreateTime)
                .orderByAsc(UserBean::getId)
                .page(userBeanIPage);
        IPage<UserPageVO> userPageVOIPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        List<UserBean> records = page.getRecords();
        List<UserPageVO> userPageVOList = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(records)){
            records.forEach(userBean -> {
                UserPageVO userPageVO = new UserPageVO();
                BeanKit.copyProperties(userBean, userPageVO);
                // 单位信息
                if(StringUtils.isNotBlank(userPageVO.getOrgId())){
                    userPageVO.setOrgName(orgService.findOrgNameByOrgId(userPageVO.getOrgId()));
                }
                
                List<String> roleIdList = Lists.newArrayList();
                List<String> roleNameList = Lists.newArrayList();
                // 角色信息
                List<String> roleRelaIdList = userRoleRelaService.findRoleIdByUserId(userPageVO.getId());
                if(CollectionUtils.isNotEmpty(roleRelaIdList)){
                    List<RoleBaseVO> roleBaseVOList = roleService.findRoleNameByRoleIdIn(roleRelaIdList);
                    if(CollectionUtils.isNotEmpty(roleBaseVOList)){
                        roleBaseVOList.forEach(roleBaseVO -> {
                            roleNameList.add(roleBaseVO.getName());
                            roleIdList.add(roleBaseVO.getId());    
                        });
                        userPageVO.setRoleIdList(roleIdList);
                        userPageVO.setRoleNameList(roleNameList);
                    }
                }

                // 第三方账号
                UserThirdPartyBean userThirdPartyBean = userThirdPartyService.lambdaQuery().eq(UserThirdPartyBean::getUserId, userPageVO.getId()).one();
                if(Objects.nonNull(userThirdPartyBean)){
                    UserThirdPartySimpleVO userThirdPartySimpleVO = new UserThirdPartySimpleVO();
                    BeanKit.copyProperties(userThirdPartyBean, userThirdPartySimpleVO);
                    userPageVO.setThirdPartyAccount(userThirdPartySimpleVO);
                }

                userPageVOList.add(userPageVO);
            });
        }
        userPageVOIPage.setRecords(userPageVOList);
        return userPageVOIPage;
    }
    
    /**
     * 关联第三方账号
     *
     * @param relaAccountDTO 关联第三方账号信息
     * @return 关联状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean relaThirdParty(UserRelaAccountDTO relaAccountDTO) throws GeneralSimpleException {

        UserBean userBean = findTop(x -> x.eq(UserBean::getId, relaAccountDTO.getUserId()));
        if(Objects.nonNull(userBean)){

            List<UserThirdPartyBean> userThirdPartyBeanList = userThirdPartyService.lambdaQuery().eq(UserThirdPartyBean::getUserId, relaAccountDTO.getUserId()).list();
            UserThirdPartyBean userThirdPartyBean = null;
            if(CollectionUtils.isNotEmpty(userThirdPartyBeanList)){
                userThirdPartyBean = userThirdPartyBeanList.get(0);

                userThirdPartyBean.setAccountName(relaAccountDTO.getAccountName());
                userThirdPartyBean.setAccountId(relaAccountDTO.getAccountId());
                userThirdPartyBean.setFullName(relaAccountDTO.getFullName());
                userThirdPartyService.updateById(userThirdPartyBean);
            }else{
                userThirdPartyBean = new UserThirdPartyBean();
                userThirdPartyBean.setId(BaseCommonUtils.generateUUID());
                userThirdPartyBean.setUserId(relaAccountDTO.getUserId());

                userThirdPartyBean.setAccountName(relaAccountDTO.getAccountName());
                userThirdPartyBean.setAccountId(relaAccountDTO.getAccountId());
                userThirdPartyBean.setFullName(relaAccountDTO.getFullName());
                userThirdPartyService.save(userThirdPartyBean);
            }
           
        }else{
            throw new GeneralSimpleException("400020", relaAccountDTO.getUserId());
        }
        
        return null;
    }

    /**
     * 根据ID获取用户信息
     *
     * @param id 用户id
     * @return 用户信息
     */
    @Override
    public UserBaseInfoVO findById(String id) {
        UserBean userBean = this.lambdaQuery().eq(UserBean::getId, id).one();
        UserBaseInfoVO userBaseInfoVO = new UserBaseInfoVO();
        if(Objects.nonNull(userBean)){
            BeanKit.copyProperties(userBean, userBaseInfoVO);
            // 单位信息
            if(StringUtils.isNotBlank(userBaseInfoVO.getOrgId())){
                userBaseInfoVO.setOrgName(orgService.findOrgNameByOrgId(userBaseInfoVO.getOrgId()));
            }

            List<String> roleIdList = Lists.newArrayList();
            List<String> roleNameList = Lists.newArrayList();
            // 角色信息
            List<String> roleRelaIdList = userRoleRelaService.findRoleIdByUserId(userBaseInfoVO.getId());
            if(CollectionUtils.isNotEmpty(roleRelaIdList)){
                List<RoleBaseVO> roleBaseVOList = roleService.findRoleNameByRoleIdIn(roleRelaIdList);
                if(CollectionUtils.isNotEmpty(roleBaseVOList)){
                    roleBaseVOList.forEach(roleBaseVO -> {
                        roleNameList.add(roleBaseVO.getName());
                        roleIdList.add(roleBaseVO.getId());    
                    });
                    userBaseInfoVO.setRoleIdList(roleIdList);
                    userBaseInfoVO.setRoleNameList(roleNameList);
                }
            }

            // 第三方账号
            UserThirdPartyBean userThirdPartyBean = userThirdPartyService.lambdaQuery().eq(UserThirdPartyBean::getUserId, userBaseInfoVO.getId()).one();
            if(Objects.nonNull(userThirdPartyBean)){
                UserThirdPartySimpleVO userThirdPartySimpleVO = new UserThirdPartySimpleVO();
                BeanKit.copyProperties(userThirdPartyBean, userThirdPartySimpleVO);
                userBaseInfoVO.setThirdPartyAccount(userThirdPartySimpleVO);
            }

        }
    
        try {
            redisTemplate.opsForValue().set(BaseConstants.REDIS_USER_PREFIX + userBaseInfoVO.getId(), userBaseInfoVO, userKeyExpiration, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.error("用户{}, redis保存失败", userBaseInfoVO.getId());
        }
        
        return userBaseInfoVO;
    }

    /**
     * 根据用户ID删除用户信息
     *
     * @param userIdDTO 用户ID信息
     * @return 删除状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean deleteUser(UserIdDTO userIdDTO) throws GeneralSimpleException {
        boolean status = removeById(userIdDTO.getId());
        if(!status){
            throw new GeneralSimpleException("400028", userIdDTO.getId());
        }

        // 删除人员账号解绑
        personManageService.delAccount(userIdDTO.getId());
        
        
        //获取这个用户的Key
        try {
            redisTemplate.delete(BaseConstants.REDIS_USER_PREFIX + userIdDTO.getId());
        } catch (Exception e) {
            log.error("用户{}, redis删除失败", userIdDTO.getId());
        }

        return true;
    }

    /**
     * 获取用户信息
     *
     * @param userId 用户ID
     * @return 用户信息
     */
    @Override
    public UserSimpleInfoVO currentUser(String userId) throws GeneralSimpleException {
        UserBean userBean = this.lambdaQuery().eq(UserBean::getId, userId).one();
        UserSimpleInfoVO userSimpleInfoVO = new UserSimpleInfoVO();
        if(Objects.nonNull(userBean)) {

            BeanKit.copyProperties(userBean, userSimpleInfoVO);
            // 单位信息
            if (StringUtils.isNotBlank(userSimpleInfoVO.getOrgId())) {
                userSimpleInfoVO.setOrgName(orgService.findOrgNameByOrgId(userSimpleInfoVO.getOrgId()));
                
                // 所属项目部ID
                String departmentOrgId = orgService.findDepartmentOrgIdByOrgId(userSimpleInfoVO.getOrgId());
                userSimpleInfoVO.setProjectDepartmentOrgId(departmentOrgId);
                if(StringUtils.equals(userSimpleInfoVO.getProjectDepartmentOrgId(), userSimpleInfoVO.getOrgId())){
                    userSimpleInfoVO.setProjectDepartmentOrgName(userSimpleInfoVO.getOrgName());
                }else{
                    if(StringUtils.isNotBlank(userSimpleInfoVO.getProjectDepartmentOrgId())){
                        userSimpleInfoVO.setProjectDepartmentOrgName(orgService.findOrgNameByOrgId(userSimpleInfoVO.getProjectDepartmentOrgId()));    
                    }
                }
            }

            // 角色信息

            List<String> roleIdList = Lists.newArrayList();
            List<String> roleNameList = Lists.newArrayList();
            // 角色信息
            List<String> roleRelaIdList = userRoleRelaService.findRoleIdByUserId(userSimpleInfoVO.getId());
            if(CollectionUtils.isNotEmpty(roleRelaIdList)){
                List<RoleBaseVO> roleBaseVOList = roleService.findRoleNameByRoleIdIn(roleRelaIdList);
                if(CollectionUtils.isNotEmpty(roleBaseVOList)){
                    roleBaseVOList.forEach(roleBaseVO -> {
                        roleNameList.add(roleBaseVO.getName());
                        roleIdList.add(roleBaseVO.getId());
                    });
                    userSimpleInfoVO.setRoleIdList(roleIdList);
                    userSimpleInfoVO.setRoleNameList(roleNameList);
                }
            }
        }
        try {
            redisTemplate.opsForValue().set(BaseConstants.REDIS_USER_PREFIX + userSimpleInfoVO.getId(), userSimpleInfoVO, userKeyExpiration, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.error("用户{}, redis保存失败", userSimpleInfoVO.getId());
        }

        return userSimpleInfoVO;
    }

    /**
     * 根据组织ID解除用户
     *
     * @param orgId 组织ID
     * @return 解除状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean disOrgByOrgId(String orgId) {
        
        List<UserBean> userBeanList = this.lambdaQuery().eq(UserBean::getOrgId, orgId).list();
        if(CollectionUtils.isEmpty(userBeanList)){
            return true;
        }

        return this.lambdaUpdate().set(UserBean::getOrgId, null).eq(UserBean::getOrgId, orgId).update();
    }

    /**
     * 根据用户ID查询用户名称
     *
     * @param userIdList 用户ID
     * @return 用户名称
     */
    @Override
    public Map<String, String> findNameByIdIn(List<String> userIdList) {
        List<UserBean> userBeanList = this.baseMapper.findByIdIn(userIdList);
        if(CollectionUtils.isNotEmpty(userBeanList)){
            return userBeanList.stream().collect(Collectors.toMap(UserBean::getId, UserBean::getFullName));
        }
        return null;
    }

    /**
     * 根据用户名称查询用户信息
     *
     * @param fullName 用户名称
     * @return 用户信息
     */
    @Override
    public List<String> findUserIdByFullName(String fullName) {
        return this.baseMapper.findUserIdByFullName(fullName);
    }

    /**
     * 查询用户的角色信息
     *
     * @param userId 用户ID
     * @return 角色信息
     */
    @Override
    public List<String> findRoleListByUserId(String userId) {
        return userRoleRelaService.findRoleIdByUserId(userId);
    }

    /**
     * 根据用户信息查询
     *
     * @param userId 用户ID
     * @return 用户权限
     */
    @Override
    public UserPermissionInfoVO findPermissionByUserId(String userId) throws GeneralSimpleException {
        if(StringUtils.isBlank(userId)){
            throw new GeneralSimpleException("100003");
        }

        UserPermissionInfoVO permissionInfoVO = new UserPermissionInfoVO();
        List<String> roleIdList = findRoleListByUserId(userId);
        if(CollectionUtils.isNotEmpty(roleIdList)){
            permissionInfoVO.setSystemAdmin(roleIdList.contains(roleSystemAdmin));
            permissionInfoVO.setHeadOffice(roleIdList.contains(roleHeadOffice));
            permissionInfoVO.setProjectDepartment(roleIdList.contains(roleProjectDepartment));
            permissionInfoVO.setParticipatingUnit(roleIdList.contains(roleParticipatingUnit));
        }

        return permissionInfoVO;
    }

    /**
     * 根据用户ID查询用户状态
     *
     * @param accountObjId 用户ID
     * @return 用户状态
     */
    @Override
    public String findStatusByUserId(String accountObjId) {
        UserBean userBean = this.getById(accountObjId);
        if(Objects.nonNull(userBean)){
            return userBean.getStatus();
        }
        return null;
    }

    /**
     * 更新用户账号信息
     *
     * @param name         用户名
     * @param orgId        所属单位
     * @param accountObjId 用户ID
     * @return
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean updateNameAndOrdIdByAccountId(String name, String orgId, String accountObjId) {
        UserBean userBean = getById(accountObjId);
        if(Objects.nonNull(userBean)){
            userBean.setFullName(name);
            userBean.setOrgId(orgId);
            return updateById(userBean);
        }
        return false;
    }

    /**
     * 查询所有的总部管理员用户
     *
     * @return 管理员用户ID
     */
    @Override
    public List<String> findAllHeadOfficeUserId() {
        return userRoleRelaService.findUserIdByRoleId(roleHeadOffice);
    }

    /**
     * 根据所属项目部ID查询项目部管理员ID
     *
     * @param projectDepartmentObjId 项目部ID
     * @return 用户ID
     */
    @Override
    public List<String> findProjectDepartmentAdminUserIdByProjectDepartmentId(String projectDepartmentObjId) {
        List<String> userIdList = userRoleRelaService.findUserIdByRoleId(roleProjectDepartment);
        if(CollectionUtils.isNotEmpty(userIdList)){
            List<UserBean> userBeanList = this.lambdaQuery()
                    .eq(UserBean::getOrgId, projectDepartmentObjId)
                    .in(UserBean::getId, userIdList)
                    .list();    
            if(CollectionUtils.isNotEmpty(userBeanList)){
                return userBeanList.stream().map(UserBean::getId).collect(Collectors.toList());
            }
        }
        return null;
    }

    @Override
    public List<String> findProjectDepartmentAdminUserIdByProjectDepartmentIdIn(List<String> orgIdList) {
        List<String> userIdList = userRoleRelaService.findUserIdByRoleId(roleProjectDepartment);
        if(CollectionUtils.isNotEmpty(userIdList)){
            List<UserBean> userBeanList = this.lambdaQuery()
                    .in(UserBean::getOrgId, orgIdList)
                    .in(UserBean::getId, userIdList)
                    .list();
            if(CollectionUtils.isNotEmpty(userBeanList)){
                return userBeanList.stream().map(UserBean::getId).collect(Collectors.toList());
            }
        }
        return null;
    }


    /**
     * 校验用户是否是系统管理员
     *
     * @return 是否是系统管理员
     */
    @Override
    public boolean checkAdminByUser() throws GeneralSimpleException {
        String userId = BaseCommonUtils.extractUserIdtByToken();
        return checkRole(userId, roleSystemAdmin);
    }

    @Override
    public boolean checkAdminByUser(String userId) throws GeneralSimpleException {
        return checkRole(userId, roleSystemAdmin);
    }

    @Override
    public boolean checkHeadOffice() throws GeneralSimpleException {
        String userId = BaseCommonUtils.extractUserIdtByToken();
        return checkRole(userId, roleHeadOffice);
    }

    @Override
    public boolean checkProjectDepartment() throws GeneralSimpleException {
        String userId = BaseCommonUtils.extractUserIdtByToken();
        return checkRole(userId, roleProjectDepartment);
    }

    @Override
    public boolean checkProjectDepartment(String userId) throws GeneralSimpleException {
        return checkRole(userId, roleProjectDepartment);
    }

    @Override
    public boolean checkCJDWByUser() throws GeneralSimpleException {
        String userId = BaseCommonUtils.extractUserIdtByToken();
        return checkRole(userId, roleParticipatingUnit);
    }

    @Override
    public boolean checkCJDWByUser(String userId) throws GeneralSimpleException {
        return checkRole(userId, roleParticipatingUnit);
    }

    @Override
    public boolean checkGeneralContractingUnit() throws GeneralSimpleException {
        String userId = BaseCommonUtils.extractUserIdtByToken();
        return checkRole(userId, roleGeneralContracting);
    }

    @Override
    public boolean checkGeneralContractingUnit(String userId) throws GeneralSimpleException {
        return checkRole(userId, roleGeneralContracting);
    }
    
    private boolean checkRole(String userId, String roleId) throws GeneralSimpleException {
        
        if(StringUtils.isBlank(userId)){
            throw new GeneralSimpleException("100003");
        }

        UserBaseInfoVO userBaseInfoVO = findById(userId);
        if(Objects.nonNull(userBaseInfoVO)){
            List<String> roleIdList = userBaseInfoVO.getRoleIdList();
            return CollectionUtils.isNotEmpty(roleIdList) && roleIdList.contains(roleId);
        }
        return false;
    }

    @Override
    public boolean checkHeadOffice(String userId) throws GeneralSimpleException {
        if(StringUtils.isBlank(userId)){
            throw new GeneralSimpleException("100003");
        }

        UserBaseInfoVO userBaseInfoVO = findById(userId);
        if(Objects.nonNull(userBaseInfoVO)){
            List<String> roleIdList = userBaseInfoVO.getRoleIdList();
            return CollectionUtils.isNotEmpty(roleIdList) && roleIdList.contains(roleHeadOffice);
        }
        return false;
    }

    /**
     * 查询系统所有系统管理员ID
     *
     * @return 系统管理员用户ID
     */
    @Override
    public List<String> findAllSystemAdminUserId() {
        return userRoleRelaService.findUserIdByRoleId(roleSystemAdmin);
    }

    /**
     * 根据用户信息查询用户单位
     *
     * @param userIdList 用户ID
     * @return 用户ID和单位
     */
    @Override
    public Map<String, String> findUserAndOrgByUserIdIn(List<String> userIdList) {
        if(CollectionUtils.isNotEmpty(userIdList)){
            List<UserBean> userBeanList = this.lambdaQuery().in(UserBean::getId, userIdList).list();
            if(CollectionUtils.isNotEmpty(userBeanList)){
                return userBeanList.stream().collect(Collectors.toMap(UserBean::getId, UserBean::getOrgId));
            }
        }
        return null;
    }

    /**
     * 账号禁用
     *
     * @param accountObjId 账号
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void disable(String accountObjId) {
        UserBean userBean = getById(accountObjId);
        if(Objects.nonNull(userBean)){
            userBean.setStatus(BaseCodeConstants.CodeType_UserStatus.KEY_UserStatus02);
            updateById(userBean);
        }
    }

    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void disable(List<String> accountObjIdList) {
        List<UserBean> userBeanList = this.lambdaQuery().in(UserBean::getId, accountObjIdList).list();
        if(CollectionUtils.isNotEmpty(userBeanList)){
            userBeanList.forEach(userBean -> userBean.setStatus(BaseCodeConstants.CodeType_UserStatus.KEY_UserStatus02));
            updateBatchById(userBeanList);
        }
    }

    /**
     * 根据用户ID查询用户账号信息
     *
     * @param accountObjId 用户账号
     * @return 用户账号信息
     */
    @Override
    public UserBaseInfoVO findInfoByUserId(String accountObjId) {
        UserBean userBean = this.getById(accountObjId);
        UserBaseInfoVO userBaseInfoVO = null;
        if(Objects.nonNull(userBean)){
            userBaseInfoVO = new UserBaseInfoVO();
            BeanUtils.copyProperties(userBean, userBaseInfoVO);
        }
        return userBaseInfoVO;
    }

    /**
     * 更新用户账号信息
     *
     * @param name         姓名
     * @param orgId        单位
     * @param status       性别
     * @param accountObjId 账号
     * @return
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean updateUserInfoById(String name, String orgId, String status, String accountObjId) {
        boolean isUpdate = false;
        UserBean userBean = getById(accountObjId);
        if(!StringUtils.equals(userBean.getFullName(), name)){
            isUpdate = true;
            userBean.setFullName(name);
        }
        
        if(!StringUtils.equals(userBean.getOrgId(), orgId)){
            isUpdate = true;
            userBean.setOrgId(orgId);
        }
        
        if(!StringUtils.equals(userBean.getStatus(), status)){
            isUpdate = true;
            userBean.setStatus(status);
        }

        if(isUpdate){
            return updateById(userBean);     
        }else{
            return true;
        }
    }

    /**
     * 更新账号其用状态
     *
     * @param newStatus    新的状态
     * @param accountObjId 用户账号ID
     * @param oldStatus    旧的状态
     * @return 更新标识
     */
    @Override
    public Boolean updateStatusByIdAndStatus(String newStatus, String accountObjId, String oldStatus) {
        List<UserBean> userBeanList = this.lambdaQuery()
                .eq(UserBean::getId, accountObjId)
                .eq(UserBean::getStatus, oldStatus).list();
        if(CollectionUtils.isNotEmpty(userBeanList)){
            return this.lambdaUpdate().set(UserBean::getStatus, newStatus)
                    .eq(UserBean::getId, accountObjId)
                    .eq(UserBean::getStatus, oldStatus)
                    .update();
        }else{
            return true;
        }
    }

    /**
     * 获得加密后的密码
     * @return 密文密码
     */
    public String encryptPassword(String salt) {
        return passwordService.generateBySm3(passwordService.getDefaultPassword(), salt);
    }
   
    public UserBean findTop(Consumer<LambdaQueryWrapper<UserBean>> consumer) {
        return lambdaQuery()
                .and(Objects.nonNull(consumer), consumer)
                .last(" LIMIT 1 ")
                .one();
    }
    
    private UserVO entityToVO(UserBean userBean){
        UserVO userVO = new UserVO();
        BeanKit.copyProperties(userBean, userVO);
        return userVO;
    }
}
